<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>药品在线招投标系统 - 数据库E-R图</title>
    <script src="https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/html2canvas@1.4.1/dist/html2canvas.min.js"></script>
    <style>
        body {
            font-family: 'Microsoft YaHei', 'SimSun', sans-serif;
            margin: 0;
            padding: 20px;
            background: #f5f5f5;
        }
        .container {
            max-width: 1600px;
            margin: 0 auto;
            background: white;
            padding: 30px;
            border-radius: 8px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
        }
        h1 {
            text-align: center;
            color: #2563eb;
            margin-bottom: 30px;
        }
        .export-buttons {
            text-align: center;
            margin-bottom: 20px;
        }
        .export-btn {
            background: #2563eb;
            color: white;
            border: none;
            padding: 12px 24px;
            border-radius: 6px;
            cursor: pointer;
            font-size: 16px;
            margin: 0 10px;
            transition: background 0.3s;
        }
        .export-btn:hover {
            background: #1e40af;
        }
        .export-btn:disabled {
            background: #94a3b8;
            cursor: not-allowed;
        }
        .status-message {
            text-align: center;
            margin: 10px 0;
            padding: 10px;
            border-radius: 6px;
            display: none;
        }
        .status-message.success {
            background: #d1fae5;
            color: #065f46;
            border: 1px solid #10b981;
        }
        .status-message.error {
            background: #fee2e2;
            color: #991b1b;
            border: 1px solid #ef4444;
        }
        .status-message.info {
            background: #dbeafe;
            color: #1e40af;
            border: 1px solid #3b82f6;
        }
        #er-container {
            background: white;
            padding: 20px;
            border: 2px solid #e2e8f0;
            border-radius: 8px;
            overflow-x: auto;
        }
        .instructions {
            margin-top: 30px;
            padding: 20px;
            background: #f1f5f9;
            border-radius: 8px;
            border-left: 4px solid #2563eb;
        }
        .instructions h2 {
            color: #1e293b;
            margin-top: 0;
        }
        .instructions ul {
            color: #64748b;
            line-height: 1.8;
        }
        .instructions table {
            width: 100%;
            border-collapse: collapse;
            margin-top: 15px;
        }
        .instructions table th,
        .instructions table td {
            padding: 10px;
            text-align: left;
            border: 1px solid #cbd5e1;
        }
        .instructions table th {
            background: #e2e8f0;
            font-weight: 600;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>药品在线招投标系统 - 数据库E-R图</h1>
        <div class="export-buttons">
            <button class="export-btn" id="exportPngBtn" onclick="exportAsPNG()">📥 导出为PNG图片</button>
            <button class="export-btn" id="exportSvgBtn" onclick="exportAsSVG()">📥 导出为SVG图片</button>
            <button class="export-btn" onclick="exportAsPNGManual()">📥 备用：导出PNG</button>
        </div>
        <div class="status-message" id="statusMessage"></div>
        <div id="er-container">
            <div class="mermaid" id="er-diagram">
erDiagram
    USERS {
        int id PK
        string username UK
        string password_hash
        string role
        string company_name
        string legal_person
        string phone
        datetime created_at
    }
    
    TENDERS {
        int id PK
        string tender_code UK
        string drug_name
        string manufacturer
        string package_req
        int total_quantity
        datetime deadline
        decimal deposit_amount
        int created_by FK
        datetime created_at
        datetime updated_at
    }
    
    BIDS {
        int id PK
        datetime bid_date
        int bidder_id FK
        string legal_person
        string phone
        int tender_id FK
        string product_batch
        datetime production_date
        datetime expiry_date
        decimal total_amount
        datetime deposit_paid_date
        datetime created_at
    }
    
    MESSAGES {
        int id PK
        int author_id FK
        int tender_id FK "可空"
        string content
        datetime created_at
    }
    
    USERS ||--o{ TENDERS : "creates"
    USERS ||--o{ BIDS : "submits"
    USERS ||--o{ MESSAGES : "posts"
    TENDERS ||--o{ BIDS : "receives"
    TENDERS ||--o{ MESSAGES : "has"
            </div>
        </div>
        <div class="instructions">
            <h2>数据库设计说明</h2>
            <h3>实体说明：</h3>
            <ul>
                <li><strong>USERS（用户表）</strong>：存储系统用户信息，包括投标单位、招标单位和管理员
                    <ul>
                        <li>id: 主键，自增</li>
                        <li>username: 用户名，唯一</li>
                        <li>password_hash: 密码哈希值</li>
                        <li>role: 用户角色（BIDDER/TENDERER/ADMIN）</li>
                        <li>company_name: 公司名称</li>
                        <li>legal_person: 法人姓名</li>
                        <li>phone: 联系电话</li>
                        <li>created_at: 创建时间</li>
                    </ul>
                </li>
                <li><strong>TENDERS（招标信息表）</strong>：存储药品招标项目信息
                    <ul>
                        <li>id: 主键，自增</li>
                        <li>tender_code: 招标项目编号，唯一</li>
                        <li>drug_name: 药品名称</li>
                        <li>manufacturer: 制药单位</li>
                        <li>package_req: 包装要求</li>
                        <li>total_quantity: 总量</li>
                        <li>deadline: 招标截止日期</li>
                        <li>deposit_amount: 投标保证金</li>
                        <li>created_by: 创建者ID（外键关联USERS）</li>
                        <li>created_at: 创建时间</li>
                        <li>updated_at: 更新时间</li>
                    </ul>
                </li>
                <li><strong>BIDS（投标信息表）</strong>：存储投标单位对招标项目的投标信息
                    <ul>
                        <li>id: 主键，自增</li>
                        <li>bid_date: 投标日期</li>
                        <li>bidder_id: 投标单位ID（外键关联USERS）</li>
                        <li>legal_person: 法人姓名</li>
                        <li>phone: 联系电话</li>
                        <li>tender_id: 招标项目ID（外键关联TENDERS）</li>
                        <li>product_batch: 产品批号</li>
                        <li>production_date: 生产日期</li>
                        <li>expiry_date: 有效期</li>
                        <li>total_amount: 投标总金额</li>
                        <li>deposit_paid_date: 投标保证金缴款日期</li>
                        <li>created_at: 创建时间</li>
                    </ul>
                </li>
                <li><strong>MESSAGES（留言表）</strong>：存储用户发布的留言，可关联到特定招标项目
                    <ul>
                        <li>id: 主键，自增</li>
                        <li>author_id: 作者ID（外键关联USERS）</li>
                        <li>tender_id: 关联招标项目ID（外键关联TENDERS，可为空）</li>
                        <li>content: 留言内容</li>
                        <li>created_at: 创建时间</li>
                    </ul>
                </li>
            </ul>
            
            <h3>关系说明：</h3>
            <table>
                <thead>
                    <tr>
                        <th>关系</th>
                        <th>类型</th>
                        <th>说明</th>
                    </tr>
                </thead>
                <tbody>
                    <tr>
                        <td>USERS → TENDERS</td>
                        <td>1对多</td>
                        <td>一个用户可以创建多个招标项目</td>
                    </tr>
                    <tr>
                        <td>USERS → BIDS</td>
                        <td>1对多</td>
                        <td>一个用户可以提交多个投标</td>
                    </tr>
                    <tr>
                        <td>USERS → MESSAGES</td>
                        <td>1对多</td>
                        <td>一个用户可以发布多条留言</td>
                    </tr>
                    <tr>
                        <td>TENDERS → BIDS</td>
                        <td>1对多</td>
                        <td>一个招标项目可以接收多个投标</td>
                    </tr>
                    <tr>
                        <td>TENDERS → MESSAGES</td>
                        <td>1对多</td>
                        <td>一个招标项目可以有多条关联留言（可选）</td>
                    </tr>
                </tbody>
            </table>
            
            <h3>导出图片方法：</h3>
            <ol>
                <li><strong>SVG导出（推荐）：</strong>点击"📥 导出为SVG图片"按钮</li>
                <li><strong>备用PNG导出：</strong>点击"📥 备用：导出PNG"按钮</li>
                <li><strong>PNG导出：</strong>点击"📥 导出为PNG图片"按钮</li>
                <li><strong>手动保存：</strong>右键点击E-R图，选择"图片另存为"</li>
            </ol>
        </div>
    </div>
    <script>
        let mermaidReady = false;
        let html2canvasReady = false;
        const statusMessage = document.getElementById('statusMessage');

        function showStatus(message, type = 'info') {
            statusMessage.textContent = message;
            statusMessage.className = 'status-message ' + type;
            statusMessage.style.display = 'block';
            setTimeout(() => {
                statusMessage.style.display = 'none';
            }, 5000);
        }

        function checkLibraries() {
            html2canvasReady = typeof html2canvas !== 'undefined';
            if (!html2canvasReady) {
                console.warn('html2canvas未加载，将使用SVG导出作为备用方案');
            }
        }

        function waitForMermaid(callback) {
            const checkInterval = setInterval(() => {
                const svg = document.querySelector('.mermaid svg');
                if (svg && svg.children.length > 0) {
                    clearInterval(checkInterval);
                    mermaidReady = true;
                    if (callback) callback();
                }
            }, 100);

            setTimeout(() => {
                clearInterval(checkInterval);
                if (!mermaidReady) {
                    showStatus('E-R图加载超时，请刷新页面重试', 'error');
                }
            }, 10000);
        }

        mermaid.initialize({ 
            startOnLoad: true,
            theme: 'default',
            er: {
                fontSize: 14,
                entityPadding: 15
            }
        });

        async function exportAsPNG() {
            const btn = document.getElementById('exportPngBtn');
            btn.disabled = true;
            btn.textContent = '⏳ 正在导出...';

            try {
                checkLibraries();
                if (!html2canvasReady) {
                    showStatus('html2canvas库未加载，请使用SVG导出或备用方案', 'error');
                    btn.disabled = false;
                    btn.textContent = '📥 导出为PNG图片';
                    return;
                }

                if (!mermaidReady) {
                    showStatus('等待E-R图加载完成...', 'info');
                    await new Promise(resolve => waitForMermaid(resolve));
                    await new Promise(resolve => setTimeout(resolve, 500));
                }

                const container = document.getElementById('er-container');
                if (!container) {
                    throw new Error('容器元素未找到');
                }

                showStatus('正在生成图片，请稍候...', 'info');

                const canvas = await html2canvas(container, {
                    backgroundColor: '#ffffff',
                    scale: 2,
                    logging: false,
                    useCORS: true,
                    allowTaint: true,
                    width: container.scrollWidth,
                    height: container.scrollHeight
                });
                
                const link = document.createElement('a');
                link.download = 'database_er_diagram.png';
                link.href = canvas.toDataURL('image/png');
                document.body.appendChild(link);
                link.click();
                document.body.removeChild(link);
                
                showStatus('PNG图片已成功下载！', 'success');
            } catch (error) {
                console.error('导出PNG失败:', error);
                showStatus('PNG导出失败: ' + error.message + '。请尝试使用SVG导出或备用方案。', 'error');
            } finally {
                btn.disabled = false;
                btn.textContent = '📥 导出为PNG图片';
            }
        }

        async function exportAsPNGManual() {
            try {
                const svg = document.querySelector('.mermaid svg');
                if (!svg) {
                    showStatus('SVG元素未找到，请等待E-R图加载完成', 'error');
                    return;
                }

                showStatus('正在通过SVG生成PNG，请稍候...', 'info');

                const svgData = new XMLSerializer().serializeToString(svg);
                const svgBlob = new Blob([svgData], { type: 'image/svg+xml;charset=utf-8' });
                const svgUrl = URL.createObjectURL(svgBlob);

                const img = new Image();
                img.crossOrigin = 'anonymous';
                
                await new Promise((resolve, reject) => {
                    img.onload = resolve;
                    img.onerror = reject;
                    img.src = svgUrl;
                });

                const canvas = document.createElement('canvas');
                const ctx = canvas.getContext('2d');
                canvas.width = img.width * 2;
                canvas.height = img.height * 2;
                ctx.fillStyle = '#ffffff';
                ctx.fillRect(0, 0, canvas.width, canvas.height);
                ctx.drawImage(img, 0, 0, canvas.width, canvas.height);

                const link = document.createElement('a');
                link.download = 'database_er_diagram.png';
                link.href = canvas.toDataURL('image/png');
                document.body.appendChild(link);
                link.click();
                document.body.removeChild(link);

                URL.revokeObjectURL(svgUrl);
                showStatus('PNG图片已成功下载（通过SVG转换）！', 'success');
            } catch (error) {
                console.error('备用PNG导出失败:', error);
                showStatus('导出失败: ' + error.message, 'error');
            }
        }

        async function exportAsSVG() {
            const btn = document.getElementById('exportSvgBtn');
            btn.disabled = true;
            btn.textContent = '⏳ 正在导出...';

            try {
                if (!mermaidReady) {
                    showStatus('等待E-R图加载完成...', 'info');
                    await new Promise(resolve => waitForMermaid(resolve));
                    await new Promise(resolve => setTimeout(resolve, 500));
                }

                const svg = document.querySelector('.mermaid svg');
                if (!svg) {
                    throw new Error('SVG元素未找到，请等待E-R图加载完成');
                }

                showStatus('正在生成SVG图片...', 'info');

                const svgData = new XMLSerializer().serializeToString(svg);
                const svgWithStyle = '<?xml version="1.0" encoding="UTF-8"?>\n' + 
                    '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\n' +
                    svgData;
                
                const svgBlob = new Blob([svgWithStyle], { type: 'image/svg+xml;charset=utf-8' });
                const svgUrl = URL.createObjectURL(svgBlob);
                
                const link = document.createElement('a');
                link.download = 'database_er_diagram.svg';
                link.href = svgUrl;
                document.body.appendChild(link);
                link.click();
                document.body.removeChild(link);
                
                URL.revokeObjectURL(svgUrl);
                showStatus('SVG图片已成功下载！', 'success');
            } catch (error) {
                console.error('导出SVG失败:', error);
                showStatus('SVG导出失败: ' + error.message, 'error');
            } finally {
                btn.disabled = false;
                btn.textContent = '📥 导出为SVG图片';
            }
        }

        window.addEventListener('load', function() {
            checkLibraries();
            waitForMermaid(() => {
                showStatus('E-R图加载完成，可以开始导出了！', 'success');
            });
        });

        setTimeout(() => {
            checkLibraries();
            if (typeof html2canvas === 'undefined') {
                showStatus('提示：html2canvas库加载失败，建议使用SVG导出或备用PNG导出', 'info');
            }
        }, 2000);
    </script>
</body>
</html>

